package com.cqupt.controller;

import com.alibaba.fastjson.JSONObject;
import com.cqupt.pojo.ResponseMessage;
import com.cqupt.service.HostService;
import com.cqupt.service.ItemService;
import com.cqupt.service.LLDService;
import com.cqupt.service.MonitorService;
import com.cqupt.service.impl.ItemServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * @author ：
 * @date ：Created in 2020/11/25 9:03
 * @description：
 * @modified By：
 */
@CrossOrigin
@Controller
@RequestMapping("monitor")
@ResponseBody
public class MonitorController {
    // 初始化时，将固定的监控项添加至对应的模板
    static{
        ItemServiceImpl isi = new ItemServiceImpl();
        // 创建监控项
        isi.createItemToTemplate(LLDService.tempidListNoSNMP[0], ItemService.diskReadKey,ItemService.diskReadName);
        isi.createItemToTemplate(LLDService.tempidListNoSNMP[0], ItemService.diskWriteKey,ItemService.diskWriteName);
        // 给Windows主机类型增加监控项 磁盘读入写入
        isi.createItemToTemplate(LLDService.tempidListNoSNMP[1], ItemService.Windows_diskReadKey,ItemService.Windows_diskReadName);
        isi.createItemToTemplate(LLDService.tempidListNoSNMP[1], ItemService.Windows_diskWriteKey,ItemService.Windows_diskWriteName);
        // 给Windows主机类型添加cpu负载监控项
        isi.createItemToTemplate(LLDService.tempidListNoSNMP[1], ItemService.Windows_load_avg,ItemService.Windows_load_avg_name);
        // 给winodows添加系统日志监控项
        isi.createLogItemToTemplate(LLDService.tempidListNoSNMP[1], ItemService.Windows_sys_log,ItemService.Windows_sys_log_name);
        // 给linux添加系统监控项
        isi.createLogItemToTemplate(LLDService.tempidListNoSNMP[0], ItemService.Linux_sys_log,ItemService.Linux_sys_log_name);
    }

    @Autowired
    private MonitorService monitorService;
    @Autowired
    private HostService hostService;
    @Autowired
    private ItemService itemService ;
    /**
     *
     * @description:  监控设备总表
     * @param:
     * @return:
     * @author:
     * @time:
     */
    @RequestMapping("/get_host_list")
    public ResponseMessage getHostList(@RequestBody Map<String, Object> params){
        Integer pageNo = Integer.valueOf(params.get("pageNo").toString());
        Integer pageSize = Integer.valueOf(params.get("pageSize").toString());
//        System.out.println(pageNo +" "+ pageSize);
        // 判断主机状态
        String status = null;
        if (params.get("status") != null)
            status = params.get("status").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        final List<Map<String, Object>> resultList = monitorService.getHostList_new(pageNo,pageSize,status);
        // 获得该状态下的所有主机数量
        final Integer count = monitorService.getHostCountByStatus(status);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("count", count);
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     *
     * @description: 获取被监控设备列表(正确判断可用性和状态间关系)
     * @param:
     * @return:
     * @author:
     * @time:
     */
    @RequestMapping("/getHostListLogic")
    public ResponseMessage getHostListLogic(@RequestBody Map<String, Object> params){
        Integer pageNo = Integer.valueOf(params.get("pageNo").toString());
        Integer pageSize = Integer.valueOf(params.get("pageSize").toString());
        Integer hostType = Integer.valueOf(params.get("hostType").toString()); //Type = 0（服务器）1（网络设备）//可用/不可用
        String status = null;
        if (params.get("status") != null)
            status = params.get("status").toString();
        ResponseMessage responseMessage = new ResponseMessage();
//        逻辑分类---> 根据主机类型分为可用/不可用 传参为：hostType主机类型，status可用/不可用状态
        final List<Map<String, Object>> resultList;
//        System.out.println("logic_status:" + status);
        if (hostType == 0)  //服务器
        {
            // 获得可用设备
            resultList = monitorService.getHostListAvailClassify(pageNo, pageSize, status, 0);
        }else {   //网络设备
            resultList = monitorService.getHostListAvailClassify(pageNo, pageSize, status, 1);
        }
        // 获得该status下的所有主机
        final Integer count = monitorService.getHostCountByTypeAndStatus(hostType,status);
//        final List<Map<String, Object>> resultList = monitorService.getHostListLogic(pageNo, pageSize, status, hostType);
//        final Integer count = monitorService.getHostCountByType(hostType);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("count", count);
//            put("count","0");
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
//        System.out.println(resultMap);
        return responseMessage;
    }


    /**
     *
     * @description:  监控 可用/无 状态 设备总表
     * @param:
     * @return:
     * @author:
     * @time:
     */
    @RequestMapping("/get_avail_host_list")
    public ResponseMessage getAvailableHostList(@RequestBody Map<String, Object> params){
        Integer pageNo = Integer.valueOf(params.get("pageNo").toString());
        Integer pageSize = Integer.valueOf(params.get("pageSize").toString());
        String status = null;
        if (params.get("status") != null)
            status = params.get("status").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        // 获得所有可用设备
        final List<Map<String, Object>> resultList = monitorService.getAvailableHostList(pageNo,pageSize,status);
        final Integer count = monitorService.getHostCountByAvail();
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("count", count);
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     *
     * @description:  监控 不可用 状态 设备总表
     * @param:
     * @return:
     * @author:
     * @time:
     */
    @RequestMapping("/get_unavail_host_list")
    public ResponseMessage getUnAvailableHostList(@RequestBody Map<String, Object> params){
        Integer pageNo = Integer.valueOf(params.get("pageNo").toString());
        Integer pageSize = Integer.valueOf(params.get("pageSize").toString());
        String status = null;
        if (params.get("status") != null)
            status = params.get("status").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        // 获得所有不可用设备
        final List<Map<String, Object>> resultList = monitorService.getUnAvailableHostList(pageNo,pageSize,status);
        final Integer count = monitorService.getHostCountByUnAvail();
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("count", count);
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }


//    /**
//     *
//     * @description:  高负载设备列表
//     * @param:
//     * @return:
//     * @author:
//     * @time:
//     */
//    @RequestMapping("/get_high_load_host_list")
//    private ResponseMessage getHighLoadHostList(@RequestBody Map<String, Object> params){
//        String name = params.get("name").toString();
//        Integer pageNo = Integer.parseInt(params.get("pageNo").toString());
//        Integer pageSize =Integer.parseInt(params.get("pageSize").toString());
//        ResponseMessage responseMessage = new ResponseMessage();
//        final List<Map<String, Object>> resultList = monitorService.getHighLoadHostList(pageNo,pageSize,name);
//        Map<String, Object> resultMap = new HashMap<String, Object>(){{
//            put("result", resultList);
//        }};
//        responseMessage.setStatus(true);
//        responseMessage.setContent(resultMap);
//        return responseMessage;
//    }
    /**
     *
     * @description: 根据hostId获取监控指标
     * @param:
     * @return:
     * @author:
     * @time:
     */
    @RequestMapping("/get_item_by_host_id")
    public ResponseMessage getItemByHostId(@RequestBody Map<String, Object> params){
        String hostId = params.get("hostId").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        // 通过主机hostid获得监控项信息
        final List<Map<String, Object>> resultList = monitorService.getItemByHostId(hostId);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }
    /**
     * @description: 根据hostId通过应用集的方式获取部分指定的监控项（老版本的，已经弃用了）
     */
    @RequestMapping("/get_application_by_hostId_and_ApplicationId")
    public ResponseMessage getItemByHostIdAndApplicationId(@RequestBody Map<String, Object> params){
        String hostId = params.get("hostId").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        // 通过主机hostid获得应用信息
        List<Map<String, Object>> applicationList = monitorService.getApplicationByHostId(hostId);
        // 通过应用信息和主机hostid获得监控信息
        final List<Map<String, Object>> itemByApplication = monitorService.getItemByApplication(applicationList, hostId);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", itemByApplication);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);

        return responseMessage;
    }

    /**
     * 获得高负载信息列表
     * @param params
     * @return
     */
    @RequestMapping("/get_high_load_host_list")
    public ResponseMessage getHighLoadHostList(@RequestBody Map<String, Object> params){
        String name = params.get("name").toString();
        String type = params.get("type").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        final List<Map<String, Object>> resultList;
        if (type.equals("dashboard")) { // 获得首页高负载信息
            resultList = monitorService.getHighLoadHostList_dashboard_new(name);
        }else if(type.equals("highload")){ // 获得高负载信息
            resultList = monitorService.getHighLoadHostList_new(name);
        }else if(type.equals("highload_api")){
            // 2022.05.25 需求接口
            List<List<String>>  reclist = monitorService.getHighLoadHostList_cpu_mem_disk(name);
            Map<String, Object> resultMap = new HashMap<String, Object>(){{
                put("result", reclist);
            }};
            responseMessage.setStatus(true);
            responseMessage.setContent(resultMap);
            return responseMessage;
        }else {
            responseMessage.setStatus(false);
            responseMessage.setContent(null);
            return responseMessage;
        }

        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     * @description: 根据hostId获取流量相关
     * @param:
     * @return:
     * @author
     * @date:
     */
    @RequestMapping("/get_net_by_host_id")
    public ResponseMessage getNetByHostId(@RequestBody Map<String,Object> params){
        int type = (int) params.get("type");
        int flag = 0;
        String hostId = params.get("hostId").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        List<Map<String, Object>> dataMap = null;
        if (type == 2)
            flag = 1;

        //判断可用性类型
        if(flag == 0){//zabbix 获得服务器网络信息
            dataMap = monitorService.getNetData(hostId);
        }else if (flag == 1){//snmp 获得网络信息
            dataMap = monitorService.getInterfaceOfSnmpByHostId(hostId);
        }

        List<Map<String, Object>> finalDataMap = dataMap;
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", finalDataMap);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     * @description:  根据snmp具体获取流量数据
     * @param:
     * @return:
     * @author
     * @date:
     */
    @RequestMapping("get_net_of_snmp_by_name")
    public ResponseMessage getNetOfSnmpByName(@RequestBody Map<String, Object> params){
        String itemName = params.get("itemName").toString();
        String hotsId = params.get("hostId").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        // 通过监控项名称和主机id获得网络信息
        final List<Map<String, Object>> netHistoryData = monitorService.getNetOfSnmpByName(hotsId, itemName);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", netHistoryData);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     * @description: 首先查询指定主机是否存在日志相关的监控项，在根据查询出的日志监控项id查询对应时间段的日志
     */
    @RequestMapping("/get_log")
    public ResponseMessage getLog(@RequestBody Map<String, Object> params){
        String itemId = params.get("itemId").toString();
        String currentPage = params.get("currentPage").toString();
        //目的：截取固定时间段
        String startDate = params.get("startDate").toString();
        String endDate = params.get("endDate").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        Map<String, Object> resultMap = new HashMap<>();
        List<Map<String, Object>> logData = monitorService.getLogHistoryDataByItemId(itemId, startDate, endDate, currentPage);
        //System.out.println(logData);
        if (logData == null){
            resultMap.put("result", "暂时无法查询数据");
        }else if (logData.size() == 0){
            resultMap.put("result", "暂无数据");
        }else {
            if (logData.size() == 11){
                resultMap.put("result", logData.subList(0,10));
                resultMap.put("total",logData.get(10).get("total"));
            }else{
                int length = logData.size();
                resultMap.put("result", logData.subList(0,length));
                resultMap.put("total",logData.get(length-1).get("total"));
            }
        }

        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }
    /**
     *
     * @description: 查询cpu/内存占用前5的进程
     * @param:
     * @return:
     * @author:
     * @time:
     */
    @RequestMapping("/get_cpu_usage_by_process")
    public ResponseMessage getCpuUsageByProcess(@RequestBody Map<String, Object> params){
        String hostIp = params.get("hostIp").toString();
        String hostId = params.get("hostId").toString();
        ResponseMessage responseMessage = new ResponseMessage();
        final List<Map<String, Object>> processData = monitorService.getCpuUsageByProcess(hostIp, hostId);
        Map<String, Object> result = new HashMap<>();
        result.put("result", processData);
        responseMessage.setStatus(true);
        responseMessage.setContent(result);
        return responseMessage;
    }
//    @RequestMapping("/get_cpu_usage_by_process")
//    private ResponseMessage getCpuUsageByProcess(@RequestBody Map<String, Object> params){
//        String hostIp = params.get("hostIp").toString();
//        String userName = params.get("userName").toString();
//        String password = params.get("password").toString();
//        ResponseMessage responseMessage = new ResponseMessage();
//        final List<Map<String, Object>> processData = monitorService.getCpuUsageByProcess(hostIp, userName, password);
//        Map<String, Object> result = new HashMap<>();
//        result.put("result", processData);
//        responseMessage.setStatus(true);
//        responseMessage.setContent(result);
//        return responseMessage;
//    }

    /**
     * @description: 获取硬件信息
     *  cpu：cpu个数
     *  硬盘：暂无
     *  内存：总内存
     */
    @RequestMapping("/get_hardware")
    public ResponseMessage getHardwareInf(@RequestBody Map<String, Object> params){
        String hostId = params.get("hostId").toString();
        String[] itemsName = params.get("itemName").toString().split(",");

        ResponseMessage responseMessage = new ResponseMessage();
        List<Map<String, Object>> hardWareInf = monitorService.getItemByName(itemsName, hostId);
        Map<String, Object> resultMap = new HashMap<>();
        if (hardWareInf.size() == 0){
            resultMap.put("result", "暂时没有相关数据");
        }else {
            resultMap.put("result", hardWareInf);
        }
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;

    }

    /**
     * 报表导出所用，后面新建了一个类，此方法在这个controlelr层弃用
     * @param params
     * @return
     */
    @RequestMapping("/export_data")
    public ResponseMessage Export_Data(@RequestBody Map<String, Object> params){
        String status = params.get("status").toString();
        Integer hostType = Integer.valueOf(params.get("hostType").toString());
        monitorService.ExportData(status,hostType);
        return null;
    }


    /**
     * hostid   主机id
     * status   可用/不可用
     * hostType 服务器/网络设备
     *             0    1
     * @param params
     * @return
     */
    @RequestMapping("/export_performance_excel")
    public ResponseMessage Export_Performance_Excel(@RequestBody Map<String, Object> params){
        String hostid = params.get("hostid").toString();
        String status = params.get("status").toString();
        Integer hostType = Integer.valueOf(params.get("hostType").toString());
        monitorService.getItem_by_DataInfo(hostid,status,hostType);
        return null;
    }

    //   修改后的服务器网络接口
    @RequestMapping("/get_net_by_host_id_new")
    public ResponseMessage getServerAgentByHostId_new(@RequestBody Map<String,Object> params){
        String hostId = params.get("hostId").toString();
        ResponseMessage responseMessage = new ResponseMessage();

        //boolean flag = monitorService.setDelayAs(hostId,"5s");
        //
        ////根据hostid和类型获取网络接口自动发现规则
        //List<Map<String, Object>> dRulesOn = hostService.getNetDRulesByHostid(hostId);
        ////将获取的自动发现规则的itemid全部获取
        //ArrayList<String> ruleIdsOn = new ArrayList<>();
        //for (Map<String, Object> dRlue : dRulesOn){
        //    ruleIdsOn.add((String) dRlue.get("itemid"));
        //}
        //int sizeOn = ruleIdsOn.size();
        //String[] rulesArrOn = ruleIdsOn.toArray(new String[sizeOn]);
        ////设自动发现规则delay为1s
        //Map<String, Object> rec01 = hostService.setDRulesDelay(rulesArrOn,"7s");
        ////设置延时3分钟，随后delay设为初始值1h
        //Timer time = new Timer();
        //time.schedule(new TimerTask() {
        //    @Override
        //    public void run() {
        //        Map<String, Object> rec02 = hostService.setDRulesDelay(rulesArrOn,"1h");
        //    }
        //}, 180000);

        // 通过主机hostid获得网络信息（优化）
        Map<String, Object> dataMap = monitorService.getNetData_new(hostId);

        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", dataMap);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    // 根据itemid获取最新接口数据
    @RequestMapping("get_new_net_data_by_itemid")
    public ResponseMessage getNewDataByItemId(@RequestBody Map<String,Object> params){

        ArrayList<String> itemIds = (ArrayList<String>) params.get("itemlist");

        ResponseMessage responseMessage = new ResponseMessage();

        // 通过监控项获得网络信息数据
        List<Map<String, Object>> dataMap = monitorService.getNewNetDataByItems(itemIds);

        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", dataMap);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    //   重置网络接口的延迟时间
    @RequestMapping("/resetDelayTime")
    public ResponseMessage resetDelayTime(@RequestBody Map<String,Object> params){
        String hostId = params.get("hostid").toString();
        ResponseMessage responseMessage = new ResponseMessage();

        // 网络延迟 默认3min
        boolean flag = monitorService.setDelayAs(hostId,"3m");

        Map<String, Object> dataMap = monitorService.getNetData_new(hostId);

        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", dataMap);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }


    /**
     * @description:  修改根据snmp具体获取流量数据
     * @param:
     * @return:
     * @author
     * @date:
     */
    @RequestMapping("get_net_of_snmp_by_name_new")
    public ResponseMessage getNetOfSnmpByName_new(@RequestBody Map<String, Object> params){
        String itemName = params.get("itemName").toString();
        String hostId = params.get("hostId").toString();

        //boolean flag = monitorService.setDelayAs(hostId,"5s");
        //
        ////根据hostid和类型获取网络接口自动发现规则
        //List<Map<String, Object>> dRulesOn = hostService.getNetDRulesByHostid(hostId);
        ////将获取的自动发现规则的itemid全部获取
        //ArrayList<String> ruleIdsOn = new ArrayList<>();
        //for (Map<String, Object> dRlue : dRulesOn){
        //    ruleIdsOn.add((String) dRlue.get("itemid"));
        //}
        //int sizeOn = ruleIdsOn.size();
        //String[] rulesArrOn = ruleIdsOn.toArray(new String[sizeOn]);
        ////设自动发现规则delay为1s
        //Map<String, Object> rec01 = hostService.setDRulesDelay(rulesArrOn,"7s");
        ////设置延时3分钟，随后delay设为初始值1h
        //Timer time = new Timer();
        //time.schedule(new TimerTask() {
        //    @Override
        //    public void run() {
        //        Map<String, Object> rec02 = hostService.setDRulesDelay(rulesArrOn,"1h");
        //    }
        //}, 180000);

        ResponseMessage responseMessage = new ResponseMessage();
        // 优化后的方法
        final Map<String, Object> netHistoryData = monitorService.getNetOfSnmpByName_new(hostId, itemName);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", netHistoryData);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     * @description:  修改根据hostid具体获取流量数据
     * @param:
     * @return:
     * @author
     * @date:
     */
    @RequestMapping("get_agent_real_type_by_hostid")
    public ResponseMessage get_agent_real_type_by_hostid(@RequestBody Map<String, Object> params){
        String hostId = params.get("hostId").toString();

        ResponseMessage responseMessage = new ResponseMessage();
        int type = monitorService.getAgentTypeByHostid(hostId);
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", type);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     * 获得当前可用的主机，相比demo中的方法，此方法返回参数一样，但是只包括当下可用的设备
     * @return
     */
    @RequestMapping("/get_avail_all_online_host")
    public ResponseMessage getAllOnlineHost() {
        ResponseMessage responseMessage = new ResponseMessage();
        final List<Map<String, Object>> resultList = monitorService.getAvailAllOnlineHost();
        Map<String, Object> resultMap = new HashMap<String, Object>(){{
            put("result", resultList);
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
     * @description: 首先查询指定主机是否存在日志相关的监控项，在根据查询出的日志监控项id查询对应时间段的日志
     */
    @RequestMapping("/get_log_type")
    public ResponseMessage get_log_type(@RequestBody Map<String, Object> params){
        String hostId = params.get("hostId").toString();
        List<Map<String, String>> logItemDetails = new ArrayList<>();
        ResponseMessage responseMessage = new ResponseMessage();
        Map<String, Object> resultMap = new HashMap<>();

        //查询指定主机是否存在日志监控项
        logItemDetails = monitorService.getLogItemId(hostId);

        if (logItemDetails.size() != 0){
            responseMessage.setStatus(true);
            resultMap.put("result", logItemDetails);
            responseMessage.setContent(resultMap);
        }else {
            responseMessage.setStatus(false);
            responseMessage.setContent(null);
        }
        return responseMessage;
    }
}
